FireLens(Fluent Bit)でELBヘルスチェックのログを除外してからCloudWatch Logsへログを保存してみる
本記事ではFargateで起動するFireLens(Fluent Bit)のログルーティング設定について触れます。設定例としてELBのヘルスチェックで出力されるログを除外してからCloudWatch Logsへログを送信してみます。
-
Icons made by Freepik from www.flaticon.com
ECS, Fargateのカスタムログルーティングでよく名前を見聞きするFireLens
FireLnesはFluent Bitや、Fluentdを簡単に起動できる仕組みそのものです。Fluent Bit、Fluendでできることは、たとえばエラーログは即時確認したいからCloudWatch Logsへ送り、すべてのログはS3バケットに長期保存したいとか、ヘルスチェックのログは保存しないといったログ周りのあれこれ。ログの保存先の選択や、ログを見て振り分けの判定するために必要なのは主にFluent Bitか、Fluentdでの設定です。
カスタムログルーティングするにはFluent Bitか、Fluendの知識が重要になってきます。
検証環境
下記リンクで作成したFargateの環境を利用して検証します。新しいFireLens(Fluent Bit)のイメージを作成しECRへプッシュしてから、タスクを再デプロイして結果を確認します。
Fluent Bitの設定ファイル
ELBからヘルスチェックで生成されるログ(レコード)を除外してから、CloudWatch Logsへ送信するサンプルコンフィグを作成します。 ELBの配下にNginxコンテナ(コンテナ名: webapp)が起動しているだけの環境です。
[FILTER]
でGrepフィルタープラグインを利用してログをフィルタしていますMatch webapp-firelens*
のwebapp部分はタスク定義で指定しているコンテナ名が入ります
[SERVICE] # 取り込まれたレコードを書き出す間隔 Flush 1 # 終了までの待機時間 Grace 30 # ロギングの詳細レベル Log_Level info # フィルタープラグイン名の指定 [FILTER] # Grepフィルタープラグインで正規表現に一致したレコードを除外できます Name grep # <コンテナ名>-firelensの形式でログが出力されます Match webapp-firelens* # ヘルスチェックのレコードパターンを除外します Exclude log ^(?=.*ELB-HealthChecker\/2\.0).*$ # 送信先のプラグイン名の指定 [OUTPUT] # CloudWatch Logsへ送信 Name cloudwatch_logs Match webapp-firelens* region ap-northeast-1 log_group_name /ecs/logs/sample-test log_stream_name webapp auto_create_group true
- Configuration File - Fluent Bit: Official Manual
- Grep - Fluent Bit: Official Manual
- Amazon CloudWatch - Fluent Bit: Official Manual
Dockerfile
Dockerfileは作成した設定ファイル(extra.conf
)をコピーしているだけです。設定ファイル名、コピー先のパスは任意ですがひとつ例外があります。
/fluent-bit/etc/fluent-bit.conf
はFireLensで使用するため予約されています。使えないファイル名とパスがあることだけはご認識ください。
FROM amazon/aws-for-fluent-bit:2.18.0 COPY ./extra.conf /fluent-bit/etc/extra.conf
/fluent-bit/etc/extra.conf
の設定ファイルを読み込ませるために、タスク定義で設定ファイルまでのパス指定が必要です。
作成済みの検証環境でパスを指定済みなので省略します。もちろん設定ファイルの名前、コピー先を変更した場合はタスク定義の修正が必要になります。
"firelensConfiguration": { "type": "fluentbit", "options": { "config-file-type": "file", "config-file-value": "/fluent-bit/etc/extra.conf" }
CloudWatch Logsの出力結果
新しく作成した設定ファイルを同梱したFireLensのイメージをデプロイしました。非常にわかりにくいのですがヘルスチェックのログは記録されていません。
今回の[FILTER]
箇所を未設定のときは以下のようにELB-HealthChecker/2.0が記録されます。
{ "source": "stdout", "log": "10.0.2.245 - - [31/Jul/2021:07:18:55 +0000] \"GET / HTTP/1.1\" 200 612 \"-\" \"ELB-HealthChecker/2.0\" \"-\"", "container_id": "e6154cf1046743bbb2f00d672213f153-1393473712", "container_name": "webapp", "ecs_cluster": "sample-test-cluster", "ecs_task_arn": "arn:aws:ecs:ap-northeast-1:123456789012:task/sample-test-cluster/e6154cf1046743bbb2f00d672213f153", "ecs_task_definition": "sample-test-webapp-taskdefinition:3" }
ヘルスチェックのログは記録されていないが、その他アクセスログなどはCloudWatch Logsに記録されているため、Grepのフィルター設定は成功したと判斷します。
おわりに
Fluent Bitまたは、Fluendの設定次第で柔軟にログをルーティング、フィルタリングできます。サイドカーで起動まではECSのタスク定義(FireLens)力、ログルーティングはFluent Bitか、Fluentd力が大切になってきます。主観ですとタスク定義はあまり難しくはないです(ややこしいけど)。ログルーティング用にFluent BitかFluendの設定を学ぶことの方が難しい気がします。その他には意図通りログをフィルタし、送信したい先へ正しくルーティングできているかのテストも含めるとなかなか時間を取られます。